home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / utils / fmgr / argv.c next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  4.7 KB  |  249 lines

  1. /* ----------------------------------------------------------------
  2.  *    argv.c
  3.  *
  4.  *    $Header: /private/postgres/src/utils/fmgr/RCS/argv.c,v 1.4 1991/03/04 13:56:10 mao Exp $
  5.  * ----------------------------------------------------------------
  6.  */
  7.  
  8. #include <ctype.h>
  9. #include <stdio.h>
  10.  
  11. /***********************************************************************
  12. **
  13. ** These routines build argv's.  An "argv" is a null-terminated array
  14. ** of pointers to strings.  Argv's are often declared as char** or
  15. ** char* foo [];
  16. ** 
  17. ** char***
  18. ** argv_new() 
  19. **
  20. **    returns a structure which is a "scaffold" for building up
  21. **    an argv. At any point, the structure will contain an argv in its
  22. **    first field.  If it overflows, a new, larger one is substituted,
  23. **    and the old one discarded.  So don't keep direct references to the argv
  24. **    unless you are not going to put any more stuff into it.
  25. **
  26. **    Say 
  27. **         char*** scaffold = (char***)argv_new();
  28. **    
  29. **    Then, when the argv is completed, dereference it...
  30. ** 
  31. **         char** complete_argv = *scaffold;
  32. **
  33. **    Then free the scaffold if you wish...
  34. **
  35. **         cfree(scaffold);
  36. **
  37. **    The argv itself is also allocated by calloc, and may be cfree()'d when
  38. **    it is no longer needed.
  39. **
  40. **    argv_new() returns 0 if it runs out of memory.
  41. **
  42. ** 
  43. ** int
  44. ** argv_put(scaffold, arg) 
  45. **    char*** scaffold;
  46. **    char* arg;
  47. **
  48. **    puts an additional arg into an argv, increasing the size
  49. **    if necessary. Returns 0 on success, -1 if it runs out of memory.
  50. **
  51. ** char**
  52. ** argv_from_str(str)
  53. **   char* str
  54. **
  55. **    Parses a string and builds an argv from it.  It
  56. **    recognizes quote-marks and escapes (\).
  57. **
  58. **    For example,
  59. **
  60. **       foo bar  "foo bar"  '\'foo\''  '"foo"'
  61. **
  62. **    gets parsed into
  63. **
  64. **       foo
  65. **       bar
  66. **       foo bar
  67. **       'foo'
  68. **       "foo"
  69. **       (0)
  70. **
  71. **    The argv and its components are all allocated by calloc().
  72. **    Returns 0 if it runs out of memory.
  73. **    
  74. **
  75. ************************************************************************/
  76.  
  77.  
  78.  
  79. struct argv_rec
  80.   { char** value;
  81.     int size;
  82.     int place;
  83.   };
  84.  
  85.  
  86. argv_put(argv, str)
  87.   struct argv_rec * argv;
  88.   char* str;
  89. {
  90.   if (argv->place + 1 == argv->size) /* oops.. overflow. */
  91.     {
  92.       char** old_argv = argv->value;
  93.       int old_size = argv->size;
  94.  
  95.       argv->size = argv->size *2;
  96.       argv->value = (char**)calloc(1, argv->size*sizeof(char*));
  97.       if(argv->value == 0) { return -1; }
  98.       bcopy(old_argv, argv->value, old_size * sizeof(char*));
  99.       free(old_argv);
  100.     }
  101.  
  102.   argv->value[argv->place] = str;
  103.   argv->place++;
  104.  
  105.   return 0;
  106.  
  107. }
  108.  
  109.  
  110. struct argv_rec *
  111. argv_new()
  112. {
  113.   struct argv_rec* retval = 
  114.     (struct argv_rec*) calloc(1,sizeof(struct argv_rec));
  115.   if (retval == 0) return 0;
  116.  
  117.   retval->value = (char**)calloc(1, 2*sizeof(char*));
  118.   if(retval->value == 0) { free(retval); return 0; }
  119.  
  120.   retval->size = 2;
  121.   retval->place = 0;
  122.  
  123.   return retval;
  124. }
  125.  
  126.  
  127. static char*
  128. strip(strp)
  129.   char** strp;
  130. {
  131.   char* str = strp? *strp: 0;
  132.   char* buffer;
  133.   char  quote = 0;
  134.   char* next_p;
  135.  
  136.   if(str == 0 || *str == 0) return 0;
  137.  
  138.   buffer = (char*)malloc(strlen(str)+1);
  139.   if(buffer == 0) return 0;
  140.  
  141.   next_p  = buffer;
  142.  
  143.   while (isspace(*str)) str++;
  144.  
  145.   if(*str == '\'' || *str == '"' ) quote = *str++;
  146.  
  147.   while(*str && !(isspace(*str) && !quote) && !(quote && *str == quote))
  148.     {
  149.       if(*str == '\\') str++;
  150.       *next_p++ = *str++;
  151.     }
  152.  
  153.   if(*str && (quote && *str == quote) ) str++; /* skip end-quote */
  154.  
  155.   *next_p = 0;
  156.   { char* retval = (char*)calloc(1, strlen(buffer) +1 );
  157.     if (retval) sprintf(retval, "%s", buffer);
  158.     free(buffer);
  159.     *strp = str;
  160.     return retval;
  161.   }
  162. }
  163.  
  164.  
  165. char**
  166. argv_from_str(str)
  167.   char* str;
  168. {
  169.   struct argv_rec* argv;
  170.   char* next_arg;
  171.   extern errno;
  172.  
  173.   errno = 0;
  174.  
  175.   argv = argv_new();
  176.   if(argv == 0) return 0;
  177.  
  178.   while( (next_arg = strip(&str)) != 0)
  179.     { argv_put(argv, next_arg);
  180.     }
  181.  
  182.   { char** retval = argv->value;
  183.     free(argv);
  184.     return retval;
  185.   }
  186.   
  187.   
  188. }
  189.  
  190. fprintf_argv(fp,argv)
  191.   FILE * fp;
  192.   char** argv;
  193. {
  194.   if(argv)
  195.     while(*argv) fprintf(fp, "%s\n", *argv++);
  196. }
  197.  
  198. printf_argv(argv)
  199.   char** argv;
  200. {
  201.   if(argv)
  202.     while(*argv) printf("%s\n", *argv++);
  203. }
  204.  
  205. int strcmp();
  206.  
  207. static
  208. alcomp(p,q)
  209.   char**p;
  210.   char**q;
  211. {
  212.   return strcmp(*p,*q);
  213. }
  214.  
  215. sort_argv(argc, argv)
  216.   char** argv;
  217. {
  218.  
  219.   qsort(argv, argc, sizeof(char*), alcomp );
  220.  
  221. }
  222.  
  223.  
  224. #undef testing
  225. #ifdef testing
  226. #include <stdio.h>
  227. main(argc, argv)
  228.   char** argv;
  229. {
  230.   char  buf[256];
  231.   char** argy;
  232.   int argk = 0;
  233.   char** aargh;
  234.   scanf("%[^\n]", buf);
  235.   argy = argv_from_str(buf);
  236.  
  237.   aargh = argy;
  238.  
  239.   while(*argy) { printf("%s\n", *argy++ ); }
  240.   {
  241.     char** p = aargh;
  242.     while(*p++) argk++;
  243.   }
  244.   sort_argv(argk, aargh);
  245.   while(*aargh) { printf("%s\n", *aargh++ ); }
  246.   fflush(stdout);
  247. }
  248. #endif testing
  249.